using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using RaidLog.Engine.Armory;
using RaidLog.WebClient.ImportData;

namespace RaidLog.WebClient
{
    public partial class ViewRaid : Form
    {
        LootData _LootData;

        public ViewRaid(LootData lootData)
        {
            _LootData = lootData;
            InitializeComponent();

            try
            {
                isUpdating = true;
                LoadData();
            }
            finally
            {
                isUpdating = false;
            }
            UpdateDKPString();
        }

        bool isUpdating = false;
        private void UpdateDKPString()
        {
            if (!isUpdating)
            {
                lock (this)
                {
                    if (!isUpdating)
                    {
                        isUpdating = true;
                        try
                        {
                            string dateTimeFormat = "MM/dd/yy HH:mm:ss"; // 07/01/07 21:35:24
                            StringBuilder sb2 = new StringBuilder();
                            List<string> itemsToUncheck = new List<string>();
                            Dictionary<string, RaidLog.Engine.Armory.item_tooltip.pageItemTooltip> items = new Dictionary<string, RaidLog.Engine.Armory.item_tooltip.pageItemTooltip>();
                            Dictionary<string, List<string>> bosskillgroupings = new Dictionary<string, List<string>>();
                            Dictionary<string, string> bosskillZones = new Dictionary<string, string>();
                            List<string> falseKillNames = new List<string>();
                            foreach (string lootedItem in checkedListBoxLootList.CheckedItems)
                            {
                                RaidLog.Engine.Armory.item_tooltip.pageItemTooltip item = ArmoryUtil.FindItemInfo(lootedItem);
                                if (null != item)// && item.overallQualityId == "4")
                                {
                                    string boss = null;
                                    if (null != item.itemSource.creatureName)
                                    {
                                        boss = item.itemSource.creatureName;
                                    }
                                    else
                                    {
                                        boss = item.name;
                                        falseKillNames.Add(boss);
                                    }
                                    
                                    if (!bosskillgroupings.ContainsKey(boss))
                                    {
                                        bosskillgroupings[boss] = new List<string>();
                                        bosskillZones[boss] = item.itemSource.areaName;
                                    }
                                    bosskillgroupings[boss].Add(item.name);
                                    items[item.name] = item;
                                }
                                else
                                {
                                    itemsToUncheck.Add(lootedItem);
                                }
                            }
                            foreach (string itemToUncheck in itemsToUncheck)
                            {
                                UncheckItem(itemToUncheck);
                            }
                            foreach (string kill in bosskillgroupings.Keys)
                            {
                                StringBuilder sb = new StringBuilder();
                                using (PseudoXmlTagAppender.PseudoXmlTab(sb, "RaidInfo"))
                                {
                                    WriteKey(sb, "key", _LootData.Raid[0].StartTime.ToString(dateTimeFormat));
                                    WriteKey(sb, "start", _LootData.Raid[0].StartTime.ToString(dateTimeFormat));
                                    WriteKey(sb, "zone", bosskillZones[kill]);
                                    #region PlayerInfos
                                    List<string> raidersToUncheck = new List<string>();
                                    using (PseudoXmlTagAppender.PseudoXmlTab(sb, "PlayerInfos"))
                                    {
                                        int keycounter = 1;
                                        foreach (string raider in checkedListBoxRaiders.CheckedItems)
                                        {
                                            RaidLog.Engine.Armory.character_sheet.pageCharacterInfo charInfo = null;
                                            StringBuilder sb1 = new StringBuilder();
                                            using (PseudoXmlTagAppender.PseudoXmlTab(sb1, "key" + keycounter++))
                                            {
                                                charInfo = ArmoryUtil.GetCharInfo(raider);
                                                if (null != charInfo.character)
                                                {
                                                    WriteKey(sb1, "name", charInfo.character[0].name);
                                                    WriteKey(sb1, "race", charInfo.character[0].race.Replace(" ", ""));
                                                    WriteKey(sb1, "guild", charInfo.character[0].guildName);
                                                    WriteKey(sb1, "sex", (charInfo.character[0].gender == "Male") ? "2" : "3");
                                                    WriteKey(sb1, "class", charInfo.character[0].@class.ToUpper());
                                                    WriteKey(sb1, "level", charInfo.character[0].level);
                                                }
                                                else
                                                {
                                                    raidersToUncheck.Add(raider);
                                                    keycounter--;
                                                }
                                            }
                                            if (null != charInfo.character)
                                            {
                                                sb.Append(sb1);
                                            }
                                        }
                                    }
                                    foreach (string raiderToUncheck in raidersToUncheck)
                                    {
                                        UncheckRaider(raiderToUncheck);
                                    }
                                    #endregion
                                    #region BossKills
                                    using (PseudoXmlTagAppender.PseudoXmlTab(sb, "BossKills"))
                                    {
                                        using (PseudoXmlTagAppender.PseudoXmlTab(sb, "key1"))
                                        {
                                            sb2.AppendLine(String.Format(@"[b][u]{0}[/u][/b]", kill));
                                            sb2.Append(@"[b]Attendees:[/b][list]");
                                            WriteKey(sb, "name", kill);
                                            DateTime time = DateTime.MinValue;
                                            int keycounter2 = 1;
                                            StringBuilder sb1 = new StringBuilder();
                                            using (PseudoXmlTagAppender.PseudoXmlTab(sb1, "attendees"))
                                            {
                                                if (falseKillNames.Contains(kill))
                                                {
                                                    List<string> includedRaiders = new List<string>();
                                                    foreach (LootData.LootCreditRow lootCreditRow in _LootData.LootCredit.Rows)
                                                    {
                                                        if (lootCreditRow.LootRowParent.Loot == kill && IsCheckedRaider(lootCreditRow.Raider) && !includedRaiders.Contains(lootCreditRow.Raider))
                                                        {
                                                            includedRaiders.Add(lootCreditRow.Raider);
                                                            time = lootCreditRow.LootRowParent.Time;
                                                            using (PseudoXmlTagAppender.PseudoXmlTab(sb1, "key" + keycounter2++))
                                                            {
                                                                WriteKey(sb1, "name", lootCreditRow.Raider);
                                                                sb2.AppendLine(String.Format(@"[b]{1}.[/b] [i]{0}[/i]", lootCreditRow.Raider, keycounter2 - 1));
                                                            }
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    foreach (LootData.KillCreditRow killCreditRow in _LootData.KillCredit.Rows)
                                                    {
                                                        if (killCreditRow.KillRowParent.Kill == kill && IsCheckedRaider(killCreditRow.Raider))
                                                        {
                                                            time = killCreditRow.KillRowParent.Time;
                                                            using (PseudoXmlTagAppender.PseudoXmlTab(sb1, "key" + keycounter2++))
                                                            {
                                                                WriteKey(sb1, "name", killCreditRow.Raider);
                                                                sb2.AppendLine(String.Format(@"[b]{1}.[/b] [i]{0}[/i]", killCreditRow.Raider, keycounter2 - 1));
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            WriteKey(sb, "time", time.ToString(dateTimeFormat));
                                            sb2.Append(@"[/list]");
                                            sb.Append(sb1.ToString());
                                        }
                                    }
                                    #endregion
                                    #region Join
                                    using (PseudoXmlTagAppender.PseudoXmlTab(sb, "Join"))
                                    {
                                        int keycounter = 1;
                                        foreach (string raider in checkedListBoxRaiders.CheckedItems)
                                        {
                                            using (PseudoXmlTagAppender.PseudoXmlTab(sb, "key" + keycounter++))
                                            {
                                                RaidLog.Engine.Armory.character_sheet.pageCharacterInfo charInfo = ArmoryUtil.GetCharInfo(raider);
                                                WriteKey(sb, "player", charInfo.character[0].name);
                                                WriteKey(sb, "race", charInfo.character[0].race);
                                                WriteKey(sb, "sex", charInfo.character[0].gender);
                                                WriteKey(sb, "class", charInfo.character[0].@class);
                                                WriteKey(sb, "level", charInfo.character[0].level);
                                                WriteKey(sb, "time", _LootData.Raid[0].StartTime.ToString(dateTimeFormat));
                                            }
                                        }
                                    }
                                    #endregion
                                    #region Leave
                                    using (PseudoXmlTagAppender.PseudoXmlTab(sb, "Leave"))
                                    {
                                        int keycounter = 1;
                                        foreach (string raider in checkedListBoxRaiders.CheckedItems)
                                        {
                                            using (PseudoXmlTagAppender.PseudoXmlTab(sb, "key" + keycounter++))
                                            {
                                                WriteKey(sb, "name", raider);
                                                WriteKey(sb, "time", _LootData.Raid[0].EndTime.ToString(dateTimeFormat));
                                            }
                                        }
                                    }
                                    #endregion
                                    #region Loot
                                    using (PseudoXmlTagAppender.PseudoXmlTab(sb, "Loot"))
                                    {
                                        sb2.Append(@"[b]Loot:[/b][list]");
                                        int keyCounterLoot = 1;
                                        foreach (string lootedItem in bosskillgroupings[kill])
                                        {
                                            List<DateTime> outputLoots = new List<DateTime>();
                                            foreach (LootData.LootCreditRow LootCreditRow in _LootData.LootCredit)
                                            {
                                                if (LootCreditRow.LootRowParent.Loot == lootedItem && !outputLoots.Contains(LootCreditRow.LootRowParent.Time))
                                                {
                                                    outputLoots.Add(LootCreditRow.LootRowParent.Time);
                                                    using (PseudoXmlTagAppender.PseudoXmlTab(sb, "key" + keyCounterLoot++))
                                                    {
                                                        sb2.AppendLine(String.Format(@"[item]{0}[/item] - {1}", lootedItem, LootCreditRow.LootRowParent.Looter));
                                                        sb2.Append("[quote][list]");
                                                        foreach (LootData.LootChatRow lootChat in LootCreditRow.LootRowParent.GetLootChatRows())
                                                        {
                                                            sb2.AppendLine(String.Format("{0} - {1}", lootChat.Time, lootChat.Text));
                                                        }
                                                        sb2.Append("[/list][/quote]");

                                                        WriteKey(sb, "ItemName", lootedItem);
                                                        WriteKey(sb, "ItemID", items[lootedItem].id);
                                                        WriteKey(sb, "Icon", items[lootedItem].icon);
                                                        WriteKey(sb, "Class", items[lootedItem].classId);
                                                        WriteKey(sb, "SubClass", "Junk");
                                                        WriteKey(sb, "Color", "ffa335ee");
                                                        WriteKey(sb, "Count", "1");
                                                        WriteKey(sb, "Player", LootCreditRow.LootRowParent.Looter);
                                                        WriteKey(sb, "Costs", "65");
                                                        WriteKey(sb, "Time", LootCreditRow.LootRowParent.Time.ToString(dateTimeFormat));
                                                        WriteKey(sb, "Zone", bosskillZones[kill]);
                                                        WriteKey(sb, "Boss", kill);
                                                    }
                                                }
                                            }
                                        }
                                        sb2.Append(@"[/list]");
                                    
                                    }
                                    #endregion
                                }
                                sb2.AppendLine(String.Format("<textarea rows=\"10\" cols=\"80\">{0}</textarea>", sb));
                            }
                            textBoxDKPString.Text = sb2.ToString();
                        }
                        finally
                        {
                            isUpdating = false;
                        }
                    }
                }
            }
        }

        private void UncheckItem(string itemToUncheck)
        {
            for (int i = 0; i < checkedListBoxLootList.Items.Count; i++)
            {
                if (((string)checkedListBoxLootList.Items[i]) == itemToUncheck)
                    checkedListBoxLootList.SetItemChecked(i, false);
            }
        }

        private void UncheckRaider(string raider)
        {
            for (int i = 0; i < checkedListBoxRaiders.Items.Count; i++)
            {
                if (((string)checkedListBoxRaiders.Items[i]) == raider)
                    checkedListBoxRaiders.SetItemChecked(i,false);
            }
        }

        private bool IsCheckedRaider(string p)
        {
            for(int i=0;i<checkedListBoxRaiders.Items.Count;i++)
            {
                if (((string)checkedListBoxRaiders.Items[i]) == p) 
                    return checkedListBoxRaiders.GetItemChecked(i);
            }
            return false;
        }

        private void WriteKey(StringBuilder sb, string p, object value)
        {
            sb.Append(String.Format("<{0}>{1}</{0}>", p, value));
        }

        private void LoadData()
        {
            foreach (LootData.LootCreditRow LootCreditRow in _LootData.LootCredit.Rows)
            {
                if (!checkedListBoxLootList.Items.Contains(LootCreditRow.LootRowParent.Loot))
                {
                    RaidLog.Engine.Armory.item_tooltip.pageItemTooltip item = ArmoryUtil.FindItemInfo(LootCreditRow.LootRowParent.Loot);
                    if (null != item)
                    {
                        if(item.overallQualityId == "4")
                        {
                            checkedListBoxLootList.Items.Add(item.name, true);
                        }
                        else
                        {
                            checkedListBoxLootList.Items.Add(item.name, false);
                        }
                    }
                }
            }
            foreach (LootData.LootCreditRow LootCreditRow in _LootData.LootCredit.Rows)
            {
                if (!checkedListBoxRaiders.Items.Contains(LootCreditRow.Raider))
                {
                    checkedListBoxRaiders.Items.Add(LootCreditRow.Raider, true);
                }
            }
        }

        private void textBoxDKPString_DoubleClick(object sender, EventArgs e)
        {
            UpdateDKPString();
        }
    }
}